package com.buddy.india.buddy.party.man.go.money;


import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class JsonUtils {
    public static <T> T fromJson(String json, Class<T> cls) {
        if (json == null || json.isEmpty() || json.equals("null")) {
            return null;
        }
        if (cls == Map.class || cls == HashMap.class) {
            try {
                JSONObject jsonObject = new JSONObject(json);
                return (T)JsonHelper.toMap(jsonObject);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        Gson gson = createGson();
        return gson.fromJson(json, cls);
    }
    public static String toJson(Object m) {
        if (m instanceof JSONObject || m instanceof JSONArray) {
            return m.toString();
        }
        Gson gson = createGson();
        return gson.toJson(m);
    }

    private static Gson createGson() {
        Gson gson = new GsonBuilder()
                .registerTypeAdapter(Date.class, new TimestampAdapter())
               .create();
        return gson;
    }
    public static class TimestampAdapter extends TypeAdapter<Date> {
        @Override
        public void write(JsonWriter out, Date value) throws IOException {
            if (value == null) {
                out.nullValue();
                return;
            }
            out.value(value.getTime());
        }

        @Override
        public Date read(JsonReader in) throws IOException {
            if (in == null) {
                return null;
            }
            return new Date(in.nextLong());
        }
    }

    static class JsonHelper {
        public static Map<String, Object> toMap(JSONObject object) throws JSONException {
            Map<String, Object> map = new HashMap();
            Iterator keys = object.keys();
            while (keys.hasNext()) {
                String key = (String) keys.next();
                map.put(key, fromJson(object.get(key)));
            }
            return map;
        }

        public static List toList(JSONArray array) throws JSONException {
            List list = new ArrayList();
            for (int i = 0; i < array.length(); i++) {
                list.add(fromJson(array.get(i)));
            }
            return list;
        }

        private static Object fromJson(Object json) throws JSONException {
            if (json == JSONObject.NULL) {
                return null;
            } else if (json instanceof JSONObject) {
                return toMap((JSONObject) json);
            } else if (json instanceof JSONArray) {
                return toList((JSONArray) json);
            } else {
                return json;
            }
        }
    }
}
